package com.bizdk.generator.core;

import cn.hutool.core.text.NamingCase;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.bizdk.generator.common.exception.ServerException;
import com.bizdk.generator.core.query.DialectQuery;
import com.bizdk.generator.entity.gen.Table;
import com.bizdk.generator.entity.gen.TableColumn;
import lombok.extern.slf4j.Slf4j;

import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

/**
 * 代码生成器 工具类
 */
@Slf4j
public class GenUtils {
    
    /**
     * 根据数据源，获取全部数据表
     *
     * @param genDataSrc 数据源
     */
    @Deprecated
    public static List<Table> getTableList(GenDataSrc genDataSrc) {
        List<Table> tableList = new ArrayList<>();
        try {
            DialectQuery query = genDataSrc.getDbQuery();
            String tableSql = query.tableSql(null);
            log.info("tableSql={}", tableSql);
            //查询数据
            PreparedStatement preparedStatement = genDataSrc.getConnection().prepareStatement(tableSql);
            ResultSet rs = preparedStatement.executeQuery();
            while (rs.next()) {
                Table table = new Table();
                table.setTableName(rs.getString(query.tableName()));
                table.setTableComment(rs.getString(query.tableComment()));
                table.setDatasrcId(genDataSrc.getId());
                tableList.add(table);
            }
            
            genDataSrc.getConnection().close();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        
        return tableList;
    }
    
    /**
     * 根据数据源，获取指定数据表
     *
     * @param genDataSrc 数据源
     * @param tableName  表名
     */
    @Deprecated
    public static Table getTable(GenDataSrc genDataSrc, String tableName) {
        try {
            DialectQuery query = genDataSrc.getDbQuery();

            String tableSql = query.tableSql(tableName);
            log.info("tableSql={}", tableSql);

            // 查询数据
            PreparedStatement preparedStatement = genDataSrc.getConnection()
                    .prepareStatement(tableSql);
            ResultSet rs = preparedStatement.executeQuery();
            if (rs.next()) {
                Table table = new Table();
                table.setTableName(rs.getString(query.tableName()));
                table.setTableComment(rs.getString(query.tableComment()));
                table.setDatasrcId(genDataSrc.getId());
                return table;
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        
        throw new ServerException("数据表不存在：" + tableName);
    }
    
    
    /**
     * 获取表字段列表
     *
     * @param genDataSrc 数据源
     * @param tableId    表ID
     * @param tableName  表名
     */
    @Deprecated
    public static List<TableColumn> getTableColumnList(GenDataSrc genDataSrc, Long tableId, String tableName) {
        List<TableColumn> columnEntityList = new ArrayList<>();
        
        try {
            DialectQuery query = genDataSrc.getDbQuery();
            String columnSql = query.columnSql();
            if (genDataSrc.getDbType() == DbType.Oracle) {
                DatabaseMetaData md = genDataSrc.getConnection().getMetaData();
                columnSql = String.format(columnSql.replace("#schema", md.getUserName()), tableName);
            } else {
                columnSql = String.format(columnSql, tableName);
            }
            log.info("columnSql={}", columnSql);
            PreparedStatement preparedStatement = genDataSrc.getConnection().prepareStatement(columnSql);
            ResultSet rs = preparedStatement.executeQuery();
            while (rs.next()) {
                TableColumn columnEntity = new TableColumn();
                columnEntity.setTableId(tableId);
                columnEntity.setColumnName(rs.getString(query.columnName()));
                String columnType = rs.getString(query.columnType());
                if (columnType.contains(" ")) {
                    columnType = columnType.substring(0, columnType.indexOf(" "));
                }
                columnEntity.setColumnType(columnType);
                columnEntity.setColumnComment(rs.getString(query.columnComment()));
                String key = rs.getString(query.columnKey());
                columnEntity.setPkItem(StringUtils.isNotBlank(key) && "PRI".equalsIgnoreCase(key));
                
                columnEntityList.add(columnEntity);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        
        return columnEntityList;
    }
    
    /**
     * 获取模块名
     *
     * @param packageName 包名
     * @return 模块名
     */
    public static String getModuleName(String packageName) {
        return StrUtil.subAfter(packageName, ".", true);
    }
    
    /**
     * 表名转驼峰并移除前后缀
     *
     * @param upperFirst   首字母大写
     * @param tableName    表名
     * @param removePrefix 删除前缀
     * @param removeSuffix 删除后缀
     * @return java.lang.String
     */
    public static String camelCase(boolean upperFirst, String tableName, String removePrefix, String removeSuffix) {
        String className = tableName;
        // 移除前缀
        if (StrUtil.isNotBlank(removePrefix)) {
            className = StrUtil.removePrefix(tableName, removePrefix);
        }
        // 移除后缀
        if (StrUtil.isNotBlank(removeSuffix)) {
            className = StrUtil.removeSuffix(className, removeSuffix);
        }
        // 是否首字母大写
        if (upperFirst) {
            return NamingCase.toPascalCase(className);
        } else {
            return NamingCase.toCamelCase(className);
        }
    }
}
